package com.zhangyan.service.impl;

import cn.hutool.core.img.ImgUtil;
import com.zhangyan.common.ErrorCode;
import com.zhangyan.exception.BusinessException;
import com.zhangyan.service.ImageService;
import com.zhangyan.utils.GithubUploader;
import jakarta.annotation.Resource;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;

@Service
public class ImageServiceImpl implements ImageService {


    @Resource
    private GithubUploader githubUploader;
    @Override
    public String uploadImage(MultipartFile multipartFile) {
        // 创建临时文件
        File tempFile = null;
        try {
            //multipartFile.getOriginalFilename() 获取文件名
            //getExtension() 获取扩展名
            //File.createTempFile(prefix, suffix) 创建临时文件  第一个参数是文件名 第二个参数是后缀
            tempFile = File.createTempFile("upload", getExtension(multipartFile.getOriginalFilename()));
            // 将上传文件写入临时文件
            multipartFile.transferTo(tempFile);
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.NOT_IMAGE,e.getMessage());
        }

        // 目标文件（压缩后的文件）
        //获取临时文件目录 /usr/ 或者  C:/
        //拼出了一个路径和文件及文件名  比如/usr/ {uuid} 原文件名.原文件
        String targetPath = System.getProperty("java.io.tmpdir") + UUID.randomUUID() + multipartFile.getOriginalFilename();
        //File 指向了这个路径
        File compressedFile = new File(targetPath);

        // 使用 Hutool 的 ImgUtil 压缩图片
        float scaleRatio = 0.5f; // 初始压缩比例
        int maxAttempts = 5; // 最大压缩尝试次数
        int attempts = 0;

        // 初次压缩
        //压缩方法 第一个参数是要压缩的文件  第二个参数是压缩完后生成的文件 第三个参数是压缩比例
        ImgUtil.scale(tempFile, compressedFile, scaleRatio);

        // 检查文件大小并继续压缩
        while (compressedFile.length() > 30 * 1024 && attempts < maxAttempts) {
            ImgUtil.scale(tempFile, compressedFile, scaleRatio);
            scaleRatio *= 0.8f;
            attempts++;
        }

        // 压缩完成后,删除未压缩的临时文件
        if (tempFile.exists()) {
            tempFile.delete();
        }

        try (FileInputStream input = new FileInputStream(compressedFile)) {
            //将压缩后的临时文件转为文件工具类对象
            //使用其构造器
            //public MockMultipartFile(String name, String originalFilename, String contentType, InputStream content) throws IOException;
            //第一个参数  正常情况下应该与前端表单传入文件名相同 这里因为内部处理所以不需要
            //第二个参数  原始文件名 xxx.xxx  这里因为内部处理所以不需要
            //第三个参数  文件的 MIME 类型（如 image/jpeg, application/octet-stream 等）  不知道文件类型时ContentType.APPLICATION_OCTET_STREAM.toString(),表示一个二进制流 知道也可以使用
            //第四个参数  文件的输入流
            MultipartFile compressedMultipartFile = new MockMultipartFile(
                    "file",
                    compressedFile.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(),
                    input
            );

            // 删除压缩后的文件
            if (compressedFile.exists()) {
                compressedFile.delete();
            }
            return this.githubUploader.upload(compressedMultipartFile);
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.NOT_IMAGE,e.getMessage());
        }
    }

    /**
     * 获取文件扩展名
     */
    private String getExtension(String fileName) {
        //contains方法查看是否包含"."
        if (fileName == null || !fileName.contains(".")) {
            return "";
        }
        //lastIndexOf找到该字符串的位置,substring方法从这个索引开始截取字符串
        return fileName.substring(fileName.lastIndexOf("."));
    }
}
